﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Reflection;
using System.Resources;
using System.Globalization;

namespace LocalServerApp.Backup
{
    class XmlWardrobeBackup
    {
        private string _path;

        public XmlWardrobeBackup()
        {
        }

        #region public methods
        public void withdrawClothesBackup(int hangerNo)
        {
            try
            {
                XDocument xmlDoc = XDocument.Load(_path + "backup.xml");

                XElement XEwardrobe = xmlDoc.Descendants("Wardrobe").First();

                XElement XActual = XEwardrobe.Descendants().Where(x => x.HasAttributes && new XAttribute(x.Attribute("HangerNo")).Value == hangerNo + "").Single();
                XActual.Remove();

                XEwardrobe.SetAttributeValue("LastUpdate", DateTime.Now.ToString());

                xmlDoc.Save(_path + "backup.xml");

                if (!File.Exists(_path + "backupStyle.xslt"))
                {
                    setupBackupStyle();
                }
            }
            catch (Exception ex)
            {
                retrySetupRutine();
            }
        }

        public void depositClothesBackup(string name, string adress, string zipcode, string cpr, string birthdate, int HangerNo)
        {
            try
            {
                XElement doc = XElement.Load(_path + "backup.xml");
                XElement XEl = doc.Descendants("Wardrobe").First();


                XElement newHangerEntry = new XElement("HangerEntry", new XAttribute("HangerNo", HangerNo), new XElement("Name", name), new XElement("Adress", adress), new XElement("Zipcode", zipcode), new XElement("Birthday", birthdate));
                XEl.Add(newHangerEntry);

                XEl.SetAttributeValue("LastUpdate", DateTime.Now.ToString());

                doc.Save(_path + "backup.xml");


                if (!File.Exists(_path + "backupStyle.xslt"))
                {
                    setupBackupStyle();
                }
            }
            catch (Exception ex)
            {
                retrySetupRutine();
            }
        }
        #endregion

        #region private helpers

        private bool retrySetupRutine()
        {
            bool succes = false;
            try
            {
                _path = getBackupDriveInfo();
                if (_path != null)
                {
                    setupBackupXml();
                    succes = true;
                }
                else
                    noBackupWarning();
            }
            catch
            {
                unknownBackupError();
            }

            return succes;
        }

        private void setupBackupXml()
        {
            try
            {
                Dictionary<int, Person> persons = DAO.getInstance().GetDepositedClothes();
                XmlTextWriter writer = new XmlTextWriter(_path + "backup.xml", null);
                Console.WriteLine();
                Console.BackgroundColor = ConsoleColor.Yellow;
                Console.ForegroundColor = ConsoleColor.Black;
                Console.WriteLine("******* INFO -Backup *******");
                Console.BackgroundColor = ConsoleColor.Black;
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Writing new backup file to: " + _path + "backup.xml");
                Console.ForegroundColor = ConsoleColor.White;
                writer.WriteStartDocument();
                writer.WriteRaw("<?xml-stylesheet type='text/xsl' href='backupStyle.xslt'?>");
                writer.WriteStartElement("Root");
                writer.WriteStartElement("Wardrobe");
                writer.WriteAttributeString("LastUpdate", DateTime.Now.ToString());

                foreach (KeyValuePair<int, Person> p in persons)
                {
                    writer.WriteStartElement("HangerEntry");
                    writer.WriteAttributeString("HangerNo", p.Key + "");

                    writer.WriteElementString("Name", p.Value.Name);
                    writer.WriteElementString("Adress", p.Value.Adress);
                    writer.WriteElementString("Zipcode", p.Value.Zipcode);
                    writer.WriteElementString("Birthday", p.Value.Birthday);

                    writer.WriteEndElement();
                }

                writer.WriteEndElement();
                writer.WriteEndElement();

                writer.WriteEndDocument();
                writer.Flush();
                writer.Close();

                if (!File.Exists(_path + "backupStyle.xslt"))
                {
                    setupBackupStyle();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine();
                Console.BackgroundColor = ConsoleColor.Red;
                Console.WriteLine("******* WARNING -backup *******");
                Console.BackgroundColor = ConsoleColor.Black;
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Error getting the deposited clothes from DB");
                Console.ForegroundColor = ConsoleColor.White;
            }
        }

        private void setupBackupStyle()
        {
            TextWriter textWriter = new StreamWriter(_path + "backupStyle.xslt");
            textWriter.Write(Properties.Resources.backupStyle);
            textWriter.Flush();
            textWriter.Close();
        }

        /// <summary>
        /// Returns ONE removable device.
        /// </summary>
        /// <returns></returns>
        private string getBackupDriveInfo()
        {
            DriveInfo[] ListDrives = DriveInfo.GetDrives();
            string result = null;

            foreach (DriveInfo Drive in ListDrives)
            {
                if (Drive.DriveType == DriveType.Removable)
                {
                    result = Drive.RootDirectory.ToString();
                    
                    try
                    {
                        TextWriter textWriter = new StreamWriter(result + "temp");
                        textWriter.Write("test");
                        textWriter.Flush();
                        textWriter.Close();
                        if (File.Exists(result + "temp"))
                        {
                            File.Delete(result + "temp");
                            break;
                        }
                        else
                        {
                            result = null;
                        }
                    }
                    catch
                    {
                        result = null;
                    }
                }
            }

            return result;
        }
        #endregion

        #region Errors send to console
        private void noBackupWarning()
        {
            Console.WriteLine();
            Console.BackgroundColor = ConsoleColor.Red;
            Console.WriteLine("******* WARNING -backup *******");
            Console.BackgroundColor = ConsoleColor.Black;
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("No backupdevice found");
            Console.WriteLine("Please insert removable device");
            Console.ForegroundColor = ConsoleColor.White;
        }

        private void unknownBackupError()
        {
            if (!retrySetupRutine())
            {
                Console.WriteLine();
                Console.BackgroundColor = ConsoleColor.Red;
                Console.WriteLine("******* WARNING -backup *******");
                Console.BackgroundColor = ConsoleColor.Black;
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Backup doesn't work probably");
                Console.ForegroundColor = ConsoleColor.White;
            }
        }
        #endregion
    }
}
